package com.ping.service;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.ping.controller.BaseController;
import com.ping.model.ResponseEnum;

public abstract class BaseService {
	public boolean add(String table,  String query){
		LinkedList<String> params = new LinkedList<>();
		LinkedList<String> values = new LinkedList<>();
		if(!parse(query, params, values)){
			return false;
		}
		
		Record record = new Record();
		genRecord(record, params, values);
		
		try {
			Db.save(table, record);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(ResponseEnum.BASESERVICE_ERROR2.getDesc());
			return false;
		}
	}
	
	public boolean add(String table,  String query, String[] params){
		LinkedList<String> values = new LinkedList<>();
		if(!parse(query, params, values)){
			return false;
		}
		
		Record record = new Record();
		genRecord(record, params, values);
		
		try {
			Db.save(table, record);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(ResponseEnum.BASESERVICE_ERROR2.getDesc());
			return false;
		}
	}
	
	public void putRefRecord(List<Record> records){
		return ;
	}

	public List<Record> find(final String query, String sql, final String[] params){
		LinkedList<String> values = new LinkedList<>();
		if(!parse(query, params, values)){
			return null;
		}
		
		String[] vs = values.toArray(new String[values.size()]);
		return Db.find(sql, vs);
	}
	
	/**
	 *@see Know the params of sql
	 */
	public void genRecord(Record record, LinkedList<String> params, LinkedList<String> values){
		for (int i = 0; i < params.size(); i++) {
			record.set(params.get(i), values.get(i));
		}
	}
	
	/**
	 *@see Do not know the params of sql
	 */
	public void genRecord(Record record, final String[] params, LinkedList<String> values){
		for (int i = 0; i < params.length; i++) {
			record.set(params[i], values.get(i));
		}
	}
	
	public boolean meet(final String query, final String[] params){
		try {
			JSONObject request = new JSONObject(query);
			JSONObject data = request.getJSONObject(BaseController.REQUEST);
			
			for (String param : params) {
				try {
					if (data.get(param) == null) {
						return false;
					}
				} catch (JSONException e) {
					// TODO: handle exception
					return false;
				}
			}
			
			return true;
		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return false;
		}
	}
	
	public boolean parse(final String query, final String[] params, List<String> values){
		try {
			JSONObject request = new JSONObject(query);
			JSONObject data = request.getJSONObject(BaseController.REQUEST);
			
			for (String param : params) {
				values.add(data.getString(param));
			}
			
			return true;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			System.out.println(ResponseEnum.JSON_PARSE_ERROR.getDesc());
			return false;
		}
	}
	
	public boolean parse(final String query, LinkedList<String> params, LinkedList<String> values){
		try {
			JSONObject request = new JSONObject(query);
			JSONObject data = request.getJSONObject(BaseController.REQUEST);
			
			Iterator<String> iterator = data.keys();
			while(iterator.hasNext()){
				params.add(iterator.next());
				values.add(data.getString(params.getLast()));
			}
			
			return true;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			System.out.println(ResponseEnum.JSON_PARSE_ERROR.getDesc());
			return false;
		}
	}
}
